use std::borrow::Cow;
use conn_port::ConnPort;
use tokio::sync::Mutex;
use tokio_serial::available_ports;
use crate::error::{AppErr, ErrWrap};


mod conn_port;
mod win_port;

static PORT: Mutex<Option<ConnPort>> = Mutex::const_new(None);


#[tauri::command]
pub fn active_ports() -> Result<Vec<String>, AppErr> {

    let ps: Vec<String> = available_ports()
    .wrap()?
    .into_iter()
    .map(|item| item.port_name)
    .collect();
    Ok(ps)
}

#[tauri::command]
pub async fn open_port(name: String) -> Result<(), AppErr> {
    let port = ConnPort::new(&name)?;

    let mut g = PORT.lock().await;
    *g = Some(port);

    Ok(())
}

#[tauri::command]
pub async fn write_port(buf: Box<[u8]>) -> Result<(), AppErr> {

    let g = PORT.lock().await;
    match g.as_ref() {
        Some(v) => {
            v.write(&buf).await?;
        }
        None => {
            return Err(AppErr::Custom(Cow::Borrowed("串口没有打开")));
        }
    };

    Ok(())
}

#[tauri::command]
pub async fn is_port_open() -> bool {
    PORT.lock().await.is_some()
}

#[tauri::command]
pub async fn close_port() -> Result<(), AppErr> {

    let mut g = PORT.lock().await;
    *g = None;

    Ok(())
}
